Godot Engineで円、円弧のカスタム描画
円の描画は、Node2Dの func _draw()で draw_circle()関数を使うだけで描画できる
円弧の描画は draw_line を複数回行うことで実装する
code:circle_arc_sample.py
extends Node2D
func _draw():
draw_circle(position, 100, Color.red)
var center = Vector2(600, 300)
var radius = 80
var angle_from = 40
var angle_to = 250
var color = Color(0, 0.5, 1.0)
draw_circle_arc(center, radius, angle_from, angle_to, color)
func draw_circle_arc(center, radius, angle_from, angle_to, color):
var nb_points = 32 # 円弧を構成する点の数を定義
var points_arc = PoolVector2Array()
for i in range(nb_points + 1):
# ラジアンの角度は3時から始まるため, 90度を減算して12時から開始に変える
var angle_point = deg2rad(angle_from + i * (angle_to - angle_from) / nb_points - 90)
# 円上の位置は、cos()とsin()を使って表す。
points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
for index_point in range(nb_points):
実行結果
https://gyazo.com/6ea42257dc563e5988bf1d50b0c047c9
左上が draw_circle()で、右下が 円弧
deg2rad関数は、degreeで表した角度(90度や360度)などを radian(0 や 3.14) に変換する関数
code:degrad
float deg2rad(deg: float)
Converts an angle expressed in degrees to radians.
r = deg2rad(180) # r is 3.141593
draw_line ではなく、draw_polygonを使って線分だけでなく面を塗りつぶすように描画できる
code:draw_polygon_sample.py
func draw_circle_arc(center, radius, angle_from, angle_to, color):
var nb_points = 32 # 円弧を構成する点の数を定義
var points_arc = PoolVector2Array()
points_arc.push_back(center)
var colors = PoolColorArray(color) for i in range(nb_points + 1):
# ラジアンの角度は3時から始まるため, 90度を減算して12時から開始に変える
var angle_point = deg2rad(angle_from + i * (angle_to - angle_from) / nb_points - 90)
# 円上の位置は、cos()とsin()を使って表す。
points_arc.push_back(center + Vector2(cos(angle_point), sin(angle_point)) * radius)
draw_polygon(points_arc, colors)
# for index_point in range(nb_points):
https://gyazo.com/68378b8a039ee1f12f7b208d6ebb8512
円弧を回転させる
angle_from, angle_to を _process で変化させて回転させる
_draw()の結果はキャッシュされているため、update()を呼び出さないと描画が更新されないことに注意
単純に degree を加算してもいいが、オーバーフローを起こす危険性があるため、wrapf()関数で0~360の範囲にwrapさせる
code:sample_rotate_arc.py
func _process(delta):
angle_from += rotation_angle * delta
angle_to += rotation_angle * delta
if angle_from > 360 and angle_to > 360:
angle_from = wrapf(angle_from, 0, 360)
angle_to = wrapf(angle_to, 0, 360)
update()